package com.innovation.ic.im.end.base.service.im_erp9.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.base.Strings;
import com.innovation.ic.im.end.base.handler.helper.HandlerHelper;
import com.innovation.ic.im.end.base.handler.im_erp9.WebSocketHandler;
import com.innovation.ic.im.end.base.mapper.im_erp9.AccountMapper;
import com.innovation.ic.im.end.base.mapper.im_erp9.GroupMapper;
import com.innovation.ic.im.end.base.mapper.im_erp9.TreeNodeMapper;
import com.innovation.ic.im.end.base.mapper.im_erp9.UserGroupMapper;
import com.innovation.ic.im.end.base.model.im_erp9.Account;
import com.innovation.ic.im.end.base.model.im_erp9.Group;
import com.innovation.ic.im.end.base.model.im_erp9.TreeNode;
import com.innovation.ic.im.end.base.pojo.ServiceResult;
import com.innovation.ic.im.end.base.pojo.constant.*;
import com.innovation.ic.im.end.base.pojo.im_erp9.GroupPojo;
import com.innovation.ic.im.end.base.service.im_erp9.GroupService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

/**
 * Group的具体实现类
 */
@Service
@Transactional
public class GroupServiceImpl extends ServiceImpl<GroupMapper, Group> implements GroupService {
    private static final Logger log = LoggerFactory.getLogger(GroupServiceImpl.class);

    @Resource
    private GroupMapper groupMapper;

    @Resource
    private AccountMapper accountMapper;

    @Resource
    private TreeNodeMapper treeNodeMapper;

    @Resource
    private UserGroupMapper userGroupMapper;

    /**
     * 处理erp删除默认群组的mq队列消息
     *
     * @param groupId 删除的默认群组id
     * @return 返回处理结果
     */
    @Override
    public ServiceResult<List<String>> handleErpDeleteGroupInfoQueueData(String groupId) {
        List<String> updateGroupIdList = new ArrayList<>();

        if (!Strings.isNullOrEmpty(groupId)) {
            int i = groupMapper.deleteById(groupId);
            if (i > 0) {
                log.info("默认群组数据删除成功,默认群组id:[{}]", groupId);
            } else {
                log.info("默认群组数据删除失败,群组不存在,群组id:[{}]", groupId);
            }

            // 查询当前部门原来属于哪个机构，进行删除
            updateGroupIdList = deleteHistoryTreeNodeDataByGroupId(groupId);
        }

        ServiceResult<List<String>> serviceResult = new ServiceResult<>();
        serviceResult.setSuccess(Boolean.TRUE);
        serviceResult.setResult(updateGroupIdList);
        return serviceResult;
    }

    /**
     * 查询分组全量数据
     *
     * @return
     */
    @Override
    public List<Group> groupListAll() {
        QueryWrapper<Group> wrapper = new QueryWrapper();
        return baseMapper.selectList(wrapper);
    }

    /**
     * 处理erp新增、修改默认群组的mq队列消息
     *
     * @param json 数据
     * @return 返回处理结果
     */
    @Override
    public ServiceResult<List<String>> handleErpAddEditGroupInfoQueueData(JSONObject json) {
        List<String> updateGroupIdList = new ArrayList<>();
        // 默认群组id
        String groupId = json.getString(RabbitMqConstants.ID_FIELD);

        // 默认群组父级id
        String fatherId = json.getString(RabbitMqConstants.FATHER_ID_FIELD);

        // 群组名称
        String name = json.getString(RabbitMqConstants.NAME_FIELD);

        // 根据默认群组id查询群组是否存在，不存在时新增默认群组
        if (!Strings.isNullOrEmpty(groupId)) {
            Group group = groupMapper.selectById(groupId);

            if (group == null) {
                group = new Group();
                group.setId(groupId);
                group.setName(name);
                group.setMembership(0);
                int insert = groupMapper.insertGroup(group);
                if (insert > 0) {
                    log.info("默认群组创建成功,群组id:[{}]", groupId);
                }
            } else {
                // 修改组织机构名称
                group.setName(name);
                int i = groupMapper.updateById(group);
                if (i > 0) {
                    log.info("默认群组修改成功,群组id:[{}]", groupId);
                }
            }

            // 查询当前部门原来属于哪个机构，进行删除
            updateGroupIdList = deleteHistoryTreeNodeDataByGroupId(groupId);

            // 处理机构树，将新创建的部门挂到父级机构下
            if (!Strings.isNullOrEmpty(fatherId)) {
                TreeNode treeNode = treeNodeMapper.selectById(fatherId);
                String children = treeNode.getChildren();
                if (TreeNodeConstants.BRACKETS.equals(children)) {

                    treeNode.setChildren(createTreeNodeChildrenString(groupId, name));
                    int update = treeNodeMapper.updateById(treeNode);
                    if (update > 0) {
                        log.info("更新组织机构表数据成功,组织机构id:[{}]", groupId);
                    }

                    // 父级原来子数据为[]说明当前机构树发生了变化
                    updateGroupIdList.add(fatherId);
                } else {
                    List<TreeNode> treeNodeList = JSON.parseArray(children, TreeNode.class);
                    if (treeNodeList != null && treeNodeList.size() > 0) {
                        // 判断用户数据是否已存在
                        boolean ifExist = Boolean.FALSE;
                        for (TreeNode treeNode1 : treeNodeList) {
                            if (treeNode1.getId().equals(groupId)) {
                                ifExist = Boolean.TRUE;
                                break;
                            }
                        }

                        if (!ifExist) {
                            TreeNode childTreeNode = new TreeNode();
                            childTreeNode.setId(groupId);
                            childTreeNode.setLabel(name);
                            childTreeNode.setType(TreeNodeType.ORGANIZATION);
                            treeNodeList.add(childTreeNode);

                            treeNode.setChildren(JSONObject.toJSONString(treeNodeList));
                            int update = treeNodeMapper.updateById(treeNode);
                            if (update > 0) {
                                log.info("更新组织机构表数据成功,组织机构id:[{}]", groupId);

                                updateGroupIdList.add(groupId);
                            }
                        } else {
                            log.info("组织机构表数据已包含部门信息,组织机构id:[{}],部门id:[{}],部门名称:[{}]", groupId, groupId, name);
                        }
                    }
                }
            }
        }

        ServiceResult<List<String>> serviceResult = new ServiceResult<>();
        serviceResult.setSuccess(Boolean.TRUE);
        serviceResult.setResult(updateGroupIdList);
        return serviceResult;
    }

    /**
     * 根据默认群组id删除历史机构数据
     *
     * @param groupId 默认群组id
     */
    private List<String> deleteHistoryTreeNodeDataByGroupId(String groupId) {
        List<String> updateGroupIdList = new ArrayList<>();

        QueryWrapper<TreeNode> queryWrapper = new QueryWrapper<>();
        queryWrapper.like(TreeNodeConstants.CHILDREN_FIELD, groupId);
        List<TreeNode> list = treeNodeMapper.selectList(queryWrapper);
        if (list != null && list.size() > 0) {
            for (TreeNode treeNode1 : list) {
                String children1 = treeNode1.getChildren();

                List<TreeNode> resultList = new ArrayList<>();
                List<TreeNode> treeNodeList1 = JSON.parseArray(children1, TreeNode.class);
                for (TreeNode treeNode2 : treeNodeList1) {
                    if (!treeNode2.getId().equals(groupId)) {
                        resultList.add(treeNode2);
                    }
                }

                treeNode1.setChildren(JSONObject.toJSONString(resultList));
                int update = treeNodeMapper.updateById(treeNode1);
                if (update > 0) {
                    log.info("更新组织机构表数据成功,组织机构id:[{}]", treeNode1.getId());
                }

                updateGroupIdList.add(treeNode1.getId());
            }
        }

        return updateGroupIdList;
    }

    /**
     * 删除group表中所有的数据
     *
     * @return
     */
    @Override
    public ServiceResult<Boolean> truncateTable() {
        ServiceResult<Boolean> serviceResult = new ServiceResult<Boolean>();
        groupMapper.truncateTable();

        serviceResult.setMessage(ServiceResult.DELETE_SUCCESS);
        serviceResult.setSuccess(Boolean.TRUE);
        return serviceResult;
    }

    /**
     * 批量插入Group对象列表
     *
     * @param groupList
     * @return
     */
    @Override
    public ServiceResult<Boolean> saveGroupList(List<Group> groupList) {
        ServiceResult<Boolean> serviceResult = new ServiceResult<Boolean>();
        baseMapper.insertBatchSomeColumn(groupList);

        serviceResult.setMessage(ServiceResult.INSERT_SUCCESS);
        serviceResult.setSuccess(Boolean.TRUE);
        return serviceResult;
    }

    /**
     * 插入Group对象，返回id
     *
     * @param group
     * @return
     */
    @Override
    public ServiceResult<String> saveGroupReturnId(Group group) {
        ServiceResult<String> serviceResult = new ServiceResult<String>();
        baseMapper.saveGroupReturnId(group);

        serviceResult.setMessage(ServiceResult.INSERT_SUCCESS);
        serviceResult.setSuccess(Boolean.TRUE);
        serviceResult.setResult(group.getId());
        return serviceResult;
    }

    /**
     * 按照group_id对ref_group_account表分组统计，并将结果更新到group_表的membership字段
     *
     * @return
     */
    @Override
    public ServiceResult<Boolean> updateMembershipSelectRefGroupAccount() {
        ServiceResult<Boolean> serviceResult = new ServiceResult<Boolean>();
        groupMapper.updateMembershipSelectRefGroupAccount();

        serviceResult.setMessage(ServiceResult.UPDATE_SUCCESS);
        serviceResult.setSuccess(Boolean.TRUE);
        return serviceResult;
    }

    /**
     * 根据id模糊查找Group对象
     *
     * @param groupId
     * @return
     */
    @Override
    public ServiceResult<Group> findByRealId(String groupId) {
        ServiceResult<Group> serviceResult = new ServiceResult<Group>();
        Group group = groupMapper.findByRealId(groupId);

        serviceResult.setMessage(ServiceResult.SELECT_SUCCESS);
        serviceResult.setSuccess(Boolean.TRUE);
        serviceResult.setResult(group);
        return serviceResult;
    }

    /**
     * 获取近期联系的默认群组和用户自定义群组。按置顶顺序降序排列，按最后聊天时间降序排列。
     * 显示未读消息数量。显示是否消息免打扰。显示最后一条消息
     *
     * @param account 账号
     * @return 查询结果
     */
    @Override
    public ServiceResult<List<GroupPojo>> findLastContact(String account) {
        ServiceResult<List<GroupPojo>> serviceResult = new ServiceResult<List<GroupPojo>>();

        List<GroupPojo> groupPojoList = groupMapper.findLastContact(account);

        // 补充默认群组成员信息
        if (groupPojoList != null && groupPojoList.size() > 0) {
            for (GroupPojo groupPojo : groupPojoList) {
                Date lastMessageTime = groupPojo.getLastMessageTime();
                Date contentInvisibleTime = groupPojo.getContentInvisibleTime();
                if (contentInvisibleTime != null && contentInvisibleTime.compareTo(lastMessageTime) > 0) {
                    groupPojo.setLastMessage(null);
                    groupPojo.setLastMessageTime(null);
                    groupPojo.setLastMessageType(null);
                }

                Map<String, Object> map = new HashMap<>();
                map.put(Constants.GROUP_ID, groupPojo.getId());
                List<Account> accounts = accountMapper.selectAccountByGroupParam(map);
                if (accounts != null && accounts.size() > 0) {
                    groupPojo.setAccountList(accounts);
                } else {
                    groupPojo.setAccountList(new ArrayList<>());
                }
            }
        }

        List<GroupPojo> userGroupPojoList = userGroupMapper.findUserGroupInfos(account);
        // 补充自定义群组成员信息
        if (userGroupPojoList != null && userGroupPojoList.size() > 0) {
            for (GroupPojo groupPojo : userGroupPojoList) {
                Date lastMessageTime = groupPojo.getLastMessageTime();
                Date contentInvisibleTime = groupPojo.getContentInvisibleTime();
                if (contentInvisibleTime != null && lastMessageTime != null && contentInvisibleTime.compareTo(lastMessageTime) > 0) {
                    groupPojo.setLastMessage(null);
                    groupPojo.setLastMessageTime(null);
                    groupPojo.setLastMessageType(null);
                }

                Map<String, Object> map = new HashMap<>();
                map.put(Constants.USER_GROUP_ID, groupPojo.getId());
                List<Account> accounts = accountMapper.selectAccountByUserGroupParam(map);
                if (accounts != null && accounts.size() > 0) {
                    groupPojo.setAccountList(accounts);
                } else {
                    groupPojo.setAccountList(new ArrayList<>());
                }
            }
        }

        groupPojoList.addAll(userGroupPojoList);

        serviceResult.setMessage(ServiceResult.SELECT_SUCCESS);
        serviceResult.setSuccess(Boolean.TRUE);
        serviceResult.setResult(groupPojoList);
        return serviceResult;
    }

    /**
     * 根据群组id获取在线人员数量
     *
     * @param groupId 群组id
     * @return 在线人员数量
     */
    @Override
    public ServiceResult<Long> getUserNumberOnlineFromRedis(String groupId) {
        ServiceResult<Long> serviceResult = new ServiceResult<Long>();
        WebSocketHandler webSocketHandler = HandlerHelper.getWebSocketHandler();
        log.info("根据groupId:[{}]查询redis中键:[{}]的数量,数量即为在线人数", groupId, RedisStorage.ONLINE_GROUP_MAP + ":" + groupId);
        Long redisKeySize = webSocketHandler.getRedisKeySize(RedisStorage.ONLINE_GROUP_MAP + ":" + groupId);
        log.info("根据groupId:[{}]查询redis中键:[{}]的数量成功,当前群组在线人数为:[{}]", groupId, RedisStorage.ONLINE_GROUP_MAP + ":" + groupId, redisKeySize);
        serviceResult.setMessage(ServiceResult.SELECT_SUCCESS);
        serviceResult.setSuccess(Boolean.TRUE);
        serviceResult.setResult(redisKeySize);
        return serviceResult;
    }

    /**
     * 处理默认群组数据
     *
     * @param groupId 默认群组id
     */
    @Override
    public ServiceResult<Boolean> handleGroupData(String groupId, String groupName) {
        Boolean result = Boolean.FALSE;

        if (!Strings.isNullOrEmpty(groupId) && !Strings.isNullOrEmpty(groupName)) {
            // 查询当前组织机构是否存在，不存在时先导入组织机构数据
            Group group = groupMapper.selectById(groupId);
            if (group == null) {
                log.info("组织机构:[{}]在Group_表中不存在,需要导入当前组织机构信息", groupId);
                Boolean importResult = importGroupByStructureId(groupId, groupName);
                if (importResult) {
                    log.info("根据id:[{}]导入组织机构信息成功", groupId);
                    result = Boolean.TRUE;
                }
            }
        }

        ServiceResult<Boolean> serviceResult = new ServiceResult<>();
        serviceResult.setSuccess(Boolean.TRUE);
        serviceResult.setMessage(ServiceResult.OPERATE_SUCCESS);
        serviceResult.setResult(result);
        return serviceResult;
    }

    /**
     * 根据id导入组织机构信息
     *
     * @param structureId 组织机构id
     * @return 返回导入结果
     */
    private Boolean importGroupByStructureId(String structureId, String groupName) {
        Boolean result = Boolean.FALSE;
        // 根据id查询erp中的组织机构信息
        Group group = new Group();
        group.setId(structureId);
        group.setName(groupName);
        int insert = groupMapper.insert(group);
        if (insert > 0) {
            result = Boolean.TRUE;
        }
        return result;
    }

    /**
     * 生成机构树子数据字符串
     *
     * @param groupId 部门id
     * @param name    部门名称
     * @return 返回结果
     */
    private String createTreeNodeChildrenString(String groupId, String name) {
        List<TreeNode> childList = new ArrayList<>();
        TreeNode childTreeNode = new TreeNode();
        childTreeNode.setId(groupId);
        childTreeNode.setLabel(name);
        childTreeNode.setType(TreeNodeType.ORGANIZATION);
        childList.add(childTreeNode);
        return JSONObject.toJSONString(childList);
    }
}